package com.ecr.hub.front.bean.managed;

import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.ecr.hub.ApplicationException;
import com.ecr.hub.MailNotSendException;
import com.ecr.hub.NumLotException;
import com.ecr.hub.RailNotAvailableException;
import com.ecr.hub.RailNotEmptyException;
import com.ecr.hub.RailNotFoundException;
import com.ecr.hub.WagonAlreadyInFormationPlanException;
import com.ecr.hub.WagonAlreadyInTrafficException;
import com.ecr.hub.WagonNotFoundException;
import com.ecr.hub.WagonNumberException;
import com.ecr.hub.WagonPosTheoriqueException;
import com.ecr.hub.front.bean.AbstractManagedBean;
import com.ecr.hub.front.validator.TimeValidator;
import com.ecr.hub.model.composition.Composition;
import com.ecr.hub.model.enumeration.HubSillonType;
import com.ecr.hub.model.enumeration.HubStack;
import com.ecr.hub.model.hub.HubTrafficController;
import com.ecr.hub.model.rail.Rail;
import com.ecr.hub.model.sillon.Sillon;
import com.ecr.hub.model.wagon.Wagon;
import com.ecr.hub.service.hub.IHubManager;
import com.ecr.hub.util.ManagedBeanUtils;
import com.ecr.hub.util.MessageUtils;

@Controller("hubManaged")
@Scope("session")
public class HubManagedBean extends AbstractManagedBean {

	// TODO vérifier que le criterion se vide bien entre chaque demande.... y a
	// t'il besoin, etc...

	private static final long serialVersionUID = 1L;

	// L'objet principal qui contient l'ensemble des voies et des wagons.
	private transient HubTrafficController hub;
	// La liste des sillons.
	private List<Sillon> lstSillons;
	// La liste des compositions pour un sillon.
	private List<Composition> lstCompositions;
	// Le sillon courant.
	private Sillon currentSillon;
	// La voie sur laquelle agit le coordinateur.
	private Rail currentRail;
	// Un objet pour éviter la prolifération de variables.
	private transient Criterion criterion;
	// Le wagon sur lequel agit le coordinateur.
	private Wagon currentWagon;
	// Le chemin d'un fichier à charger.
	private String pdfFileToLoad;

	// Le manager pour toutes les requêtes du hub.
	@Resource(name = "hubManager")
	private transient IHubManager hubManager;

	/**
	 * Constructeur
	 */
	HubManagedBean() {

		criterion = new Criterion();
	}

	/**
	 * Initialisation du panneau de visualisation pour le Hub. On charge
	 * l'ensemble des voies avec les différents wagons répartis sur le Hub.
	 */
	@PostConstruct
	public void _getHub() {

		try {
			setHub(hubManager.getHub());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	// ******************************************
	// Partie : Sillon.
	// ******************************************

	/**
	 * Récupération de tous les trains à réception. Pour cela, on récupère
	 * l'ensemble des sillons dont le statut est compris entre
	 * "Relevé de composition arrivé" et "Train non encore arrivé au Hub" et
	 * dont le type de sillon est à 'A' pour "Arrival".
	 */
	public void checkArrivals() {

		try {
			setLstSillons(hubManager.checkArrivals());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Récupération de tous les trains au départ.Pour cela, on récupère
	 * l'ensemble des sillons dont le statut est compris entre "" et
	 * "Train non encore parti du Hub" et dont le type de sillon est à 'D' pour
	 * "Departure".
	 */
	public void checkDepartures() {

		try {
			setLstSillons(hubManager.checkDepartures());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Mise à jour du commentaire pour un sillon. On récupère le sillon en cours
	 * et on passe le sillon au manager.
	 */
	public void updateSillonComment() {

		try {
			hubManager.updateSillonComment(getCurrentSillon());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Suppression d'un sillon et de l'ensemble des enregistrements qui lui sont
	 * attachés (on passe le statut du sillon à "Annulé", si le sillon est de
	 * type "Arrivée" alors on supprime tous les wagons en prévisionnel sur le
	 * hub). Il n'y a pas de contrôle bloquant sur le fait que le train ait été
	 * reçu.... permet de réparer des erreurs.
	 */
	public void deleteSillon() {

		try {
			hubManager.deleteSillon(hub, getCurrentSillon());
			if (HubSillonType.ARRIVAL.getValue().equals(
					getCurrentSillon().getType()))
				setLstSillons(hubManager.checkArrivals());
			else
				setLstSillons(hubManager.checkDepartures());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * réinitialisation complète d'un sillon, si le coordinateur s'est trompé
	 * dans son programme de travail, sur l'affectaction de la voie de reception
	 * etc.. On efface toutes les données dans le hub et on repositionne le
	 * statut du sillon. Attention, le programme de travail lui n'est pas
	 * réeinitialisé si le coordinateur a fait des modifications.
	 */
	public void initSillon() {

		try {
			hubManager.initSillon(getHub(), getCurrentSillon());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	// ******************************************
	// Partie : Programme de travail.
	// ******************************************

	/**
	 * Récupération du plan de travail. On liste dans la table hub_compo tous
	 * les enregistrements qui appartiennent au sillon d'arrivée. Cette liste
	 * est une synthèse à la fois du relevé de composition et du programme de
	 * travail. on place le sillon dans "currentSillon" afin de pouvoir le
	 * récupérer dans la méthode suivante "processWorkingPlan".
	 */
	public String getWorkingPlan() {

		try {
			setLstCompositions(hubManager.getWorkingPlan(getHub(),
					getCurrentSillon()));
			return "arrival_success_plan";
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
			return null;
		} catch (Exception e) {
			getErrorHandler(e);
			return null;
		}
	}

	/**
	 * Cette méthode permet de déplacer un wagon d'un point A à un point B, ou
	 * de déplacer simplement un wagon en changeant de position au niveau de sa
	 * voie. On déplace simplement le wagon en lancant les alertes nécessaires.
	 * La première chose est de retrouver le wagon dans la liste des
	 * compositions. Par la suite on affecte la nouvelle voie au wagon. Enfin,
	 * on demande le déplacement du wagon.
	 */
	public void moveWagonForWorkingPlan() {

		try {
			Wagon currentWagon = getLstCompositions().get(criterion.getIdx())
					.getWagon();
			currentWagon.getNextPos().setPosRailId(
					getCriterion().getPosRailId());
			hubManager.moveWagon(getHub(), currentWagon, HubStack.POS_END);
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Mise à jour du programme de travail qui a été préparé à l'aide de la
	 * méthode précédente. Tous les wagons sont déjà positionnés dans le hub,il
	 * faut juste flusher le hub dans la base et mettre à jour l'id des rails
	 * dans la table composition (au cas ou le coordinateur a demandé des
	 * modifications). Enfin, on met à jour le statut du sillon avec :
	 * "Plan de travail demandé". Puis on demande la visualisation du document
	 * pdf pour impression.
	 */
	public String requestWorkingPlan() {

		try {
			hubManager.requestWorkingPlan(getHub(), getCurrentSillon(),
					getLstCompositions());
			setPdfFileToLoad(hubManager.displayWorkingPlanPdf(
					LoginManagedBean.getConnectedUser(), getCurrentSillon()));
			return "arrival_success_print_working_plan";
		} catch (RailNotAvailableException e) {
			MessageUtils.setMessageError("hub.error.rail.available");
			return null;
		} catch (Exception e) {
			getErrorHandler(e);
			return null;
		}
	}

	/**
	 * Cette methode ne fait que mettre à jour le statut des wagons dans le hub
	 * afin de le passer à "En cours de tri". Le programme de travail a été
	 * demandé dans la méthode précédente, lorsque le coordinateur a envoyé le
	 * programme aux AFR.
	 */
	public void processWorkingPlan() {

		try {
			hubManager.processWorkingPlan(getHub(), getCurrentSillon());
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Cette méthode met à jour le statut des wagons dans le hub afin de le
	 * passer à "Trié". Il y a donc une suppression des wagons à effectuer sur
	 * la voie de reception. On ne conserve que les wagons qui sont sur les
	 * voies de tri. A la fin on redemande la liste des arrivées (le sillon de
	 * doit plus apparaitre).
	 */
	// TODO : voir pour les cas spécifiques (train qui part directement etc...)
	public void completeWorkingPlan() {

		try {
			hubManager.completeWorkingPlan(getHub(), getCurrentSillon());
			setLstSillons(hubManager.checkArrivals());
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	// ******************************************
	// Partie : Reception du train.
	// ******************************************

	/**
	 * Méthode pour la reception du train sur le hub. On positionne les
	 * différents wagons sur la voie de reception et on passe le statut du train
	 * en fonction des opérations préalablement effectuées (programme de travail
	 * effectué ou non). Ici on ne peut mettre de validator car c'est la table
	 * entière qui est envoyée, donc on teste directement les données dans la
	 * méthode. Pour les rames vides, on passe directement le statut à arrivée
	 * complétée, ce qui oblige à redemander le chargement des sillons pour
	 * quelques cas seulement ....
	 */
	public void completeArrival() {

		Date today = new Date();
		if (getCurrentSillon().getRailId() < 0)
			MessageUtils.setMessageError("arrival.rail.required");
		else if (!TimeValidator.checkTime(getCurrentSillon()
				.getRealMovementTime()))
			MessageUtils.setMessageError("arrival.time.required");
		else if (today.compareTo(getCurrentSillon().getRealMovementDate()) < 0)
			MessageUtils.setMessageError("arrival.real.date.false");
		else
			try {
				hubManager.completeArrival(getHub(), getCurrentSillon());
				setLstSillons(hubManager.checkArrivals());
			} catch (RailNotAvailableException e) {
				MessageUtils.setMessageError("hub.error.rail.available");
			} catch (WagonPosTheoriqueException e) {
				MessageUtils.setMessageError("hub.error.rail.wagon.theo");
			} catch (Exception e) {
				getErrorHandler(e);
			}
	}

	// *******************************************
	// Partie : Formation.
	// *******************************************

	/**
	 * Préparation du plan de formation. On liste l'ensemble des voies pour
	 * pouvoir dépiler les wagons sur une voie de formation ou de départ. Ici,
	 * il faut aussi contrôler qu'une voie de formation a bien été selectionnée.
	 * (On ne peut le faire avec un validator). On en profite pour récupérer le
	 * numéro de la voie pour la formation du train.
	 */
	public String getFormationPlanPhaseOne() {

		if (getCurrentSillon().getRailFormationId() == 0) {
			MessageUtils.setMessageError("fplan.rail.formation.required");
		} else if (getCurrentSillon().getRailId() == 0) {
			MessageUtils.setMessageError("fplan.rail.departure.required");
		} else {
			try {
				hubManager.getFormationPlanPhaseOne(getHub(),
						getCurrentSillon());
				return "formation_success_1_plan";
			} catch (RailNotAvailableException e) {
				MessageUtils.setMessageError("hub.error.rail.available");
			} catch (Exception e) {
				getErrorHandler(e);
			}
		}
		return null;
	}

	/**
	 * Préparation du plan de formation (phase 2). On récupère dans chaque voie
	 * le nombre de wagons à dépiler, avec l'identifiant de la voie de formation
	 * (voie cible choisie par le coordinateur) et on injecte les wagons dans la
	 * voie de formation. Suite à cette opération, on place la voie de formation
	 * dans la voie courante et on crée directement la composition.
	 */
	public String getFormationPlanPhaseTwo() {

		try {
			setLstCompositions((hubManager.getFormationPlanPhaseTwo(getHub(),
					getCurrentSillon())));
			return "formation_success_2_plan";
		} catch (NumLotException e) {
			MessageUtils.setMessageError("hub.error.numlot.suite.weak");
		} catch (RailNotFoundException e) {
			MessageUtils.setMessageError("fplan.data.required");
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (ApplicationException e) {
			MessageUtils.setMessageError("fplan.error");
		} catch (Exception e) {
			getErrorHandler(e);
		}
		return null;
	}

	/**
	 * Une fois le plan de formation validé par le coordinateur, on le
	 * sauvegarde dans la base de données, on flush le hub et on met à jour le
	 * sillon pourle passer au statut "Formation en cours". Enfin on écrit le
	 * programme de formation dans le ficher PDF.
	 */
	public String processFormationPlan() {

		try {
			hubManager.processFormationPlan(getHub(), getLstCompositions(),
					getCurrentSillon());
			setPdfFileToLoad(hubManager.displayFormationPlanPdf(
					LoginManagedBean.getConnectedUser(), getCurrentSillon()));
			return "departure_success_print_formation_plan";
		} catch (Exception e) {
			getErrorHandler(e);
			return null;
		}
	}

	/**
	 * Cette méthode met à jour le statut des wagons (et enlève les wagons qui
	 * étaient en position réelle) pour passer l'état des wagons à "Formé".
	 */
	public void completeFormationPlan() {

		try {
			hubManager.completeFormationPlan(getHub(), getCurrentSillon());
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	// *******************************************
	// Partie : Départ du train.
	// *******************************************

	/**
	 * Première méthode appelée pour le départ du train. deux cas possibles se
	 * présentent. La voie de formation est la même que celle de départ. La voie
	 * de formation est différente de celle de départ. On place les wagons sur
	 * la voie de départ (si besoin) sinon on positionne le statut des wagons
	 * directement à "Prêt au départ".
	 */
	public void requestDeparture() {

		try {
			if (getCurrentSillon().getRailId() < 0)
				MessageUtils.setMessageError("departure.rail.required");
			else {
				if (getCurrentSillon().getRailId() != getCurrentSillon()
						.getRailFormationId()) {
					hubManager.requestDeparture(getHub(), getCurrentSillon());
				} else {
					processDeparture();
				}
			}
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * On passe le train à l'état "Prêt au départ". C'est l'avant dernière étape
	 * avant que le train ne quitte le hub. Si la voie de formation est
	 * différente de la voie de départ, on la libère.
	 */
	public void processDeparture() {

		try {
			hubManager.processDeparture(getHub(), getCurrentSillon());
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Cette méthode affiche le relevé de composition au départ. On ne met pas
	 * encore le statut du train à "Parti Gevrey" car il se peut que le
	 * coordinateur détecte une erreur en visualisant le relevé de composition.
	 * La véritable validation du départ s'effectue en cliquant sur le bouton
	 * "Terminer" du relevé de composition. Ici on ne peut mettre de validator
	 * car c'est la table entière qui est envoyée, donc on teste directement les
	 * données dans la méthode.
	 */
	public String completeDeparture() {
		try {
			Date today = new Date();
			if (!TimeValidator.checkTime(getCurrentSillon()
					.getRealMovementTime()))
				MessageUtils.setMessageError("departure.time.required");
			else if ((getCurrentSillon().getRealMovementDate().compareTo(today)) > 0)
				MessageUtils.setMessageError("departure.real.date.false");
			else {
				setPdfFileToLoad(hubManager
						.displayCompositionPlanPdf(
								LoginManagedBean.getConnectedUser(),
								getCurrentSillon()));
				return "departure_success_print_composition_plan";
			}
		} catch (Exception e) {
			getErrorHandler(e);

		}
		return null;
	}

	/**
	 * On passe le train à l'état "Parti Gevrey". On supprime l'ensemble des
	 * wagons de la voie de départ, on met à jour le sillon qui disparait de la
	 * page de gestion des départs. On envoi un mail avec le relevé de
	 * composition pour TCMS. Dans tous les cas, on renvoi sur la page de
	 * gestion des départs.
	 */
	public String finalizeDeparture() {

		try {
			hubManager.completeDeparture(getHub(), getCurrentSillon());
			setLstSillons(hubManager.checkDepartures());
			// Puis le mail en dernier...
			hubManager.sendCompositionMail(LoginManagedBean.getConnectedUser());
			return "departure_success";
		} catch (MailNotSendException e) {
			MessageUtils.setMessageError("mail.not.send");
			return null;
		} catch (Exception e) {
			getErrorHandler(e);
			return null;
		}
	}

	// *******************************************
	// Partie : Méthodes générales.
	// *******************************************

	/*
	 * Cette méthode vérifie au préalable la valididé du choix utilisateur pour
	 * la voie de reception, formation, départ. On vérifie principalement que la
	 * voie est disponible et non encombrée. On réinjecte la valeur reçue dans
	 * le bon champ suivant qu'il s'agisse d'une voie à réception on non. Très
	 * important remettre le hub dans sa dernière position après le test, car si
	 * l'utilisateur ne valide pas et décide de passer à un autre train, le hub
	 * est en état instable.
	 */
	public void checkRail() {

		try {
			setCurrentSillon(lstSillons.get(getCriterion().getIdx()));
			hubManager.checkRail(getHub(), getCurrentSillon(),
					criterion.getPosRailId(), criterion.getTypeCheckRail());
		} catch (RailNotAvailableException e) {
			MessageUtils.setMessageError("hub.error.rail.available");
		} catch (RailNotEmptyException e) {
			MessageUtils.setMessageError("hub.error.rail.notempty");
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (ApplicationException e) {
			MessageUtils.setMessageNoBundleError(e.getMessage());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Méthode pour ajouter un wagon. Ici il est impossible de positionner le
	 * wagon en temps réel pour l'utilisateur car il est nécessaire d'avoir
	 * l'ensemble des données et on ne peut les avoir qu'à partir du momment ou
	 * on arrive dans cette fonction.
	 */
	public void addWagon() {

		try {
			getCurrentWagon().getNextPos().setPosRailId(
					getCurrentRail().getId());
			hubManager.addWagon(hub, getCurrentWagon());
			MessageUtils.setMessageInfo(""); // Juste pour fermer la popup.
		} catch (WagonAlreadyInTrafficException e) {
			MessageUtils.setMessageError("new.wagon.in.traffic");
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.rail.wagon.theo");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Mise à jour d'un wagon. On vérifie si le statut a changé, si la voie et /
	 * ou la position a changé. On met à jour le commentaire si changé.
	 */
	public void updateWagon() {

		try {
			hubManager.updateWagon(getHub(), getCurrentWagon());
			MessageUtils.setMessageInfo("msg.ok");
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.theo");
		} catch (RailNotAvailableException e) {
			MessageUtils.setMessageError("hub.error.rail.available");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Mise à jour de plusieurs wagons. Cette méthode permet de déplacer
	 * plusieurs wagons en une seule fois. On déplace les wagons et on modifie
	 * leur statut.
	 */
	public void updateWagons() {

		try {
			hubManager.updateWagons(getHub(), getCurrentRail(), getCriterion()
					.getPosRailId(), getCriterion().getStatusId(),
					getCriterion().getNbWagonStack());
			MessageUtils.setMessageInfo("msg.ok");
		} catch (WagonNumberException e) {
			MessageUtils.setMessageError("hub.error.nbwagons");
		} catch (WagonPosTheoriqueException e) {
			MessageUtils.setMessageError("hub.error.theo");
		} catch (RailNotAvailableException e) {
			MessageUtils.setMessageError("hub.error.rail.available");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Initialisation de la fenêtre de déplacement pour plusieurs wagons.
	 */
	public void initUpdateWagons() {
		getCriterion().setNbWagonStack(2);
		getCriterion().setPosRailId(0);
		getCriterion().setStatusId(0);
	}

	/**
	 * Méthode pour ajouter une locomotive. On place juste le booleen trailer à
	 * "false" pour indiquer qu'il s'agit d'une locomotive et on part sur la
	 * fonction standard d'ajout d'un wagon. (Par défaut avec le constructeur
	 * dans l'objet wagonType, le booléen est à "true" ).
	 */
	public void addLocomotive() {

		getCurrentWagon().getType().setTrailer(false);
		addWagon();
	}

	/**
	 * Recherche d'un wagon sur l'ensemble du hub. Si la wagon est trouvé, un
	 * message indique sur quelle voie le wagon a été trouvé et le wagon est
	 * signalisé (surbrillance ou autre) dans le hub.
	 */
	public void findWagonInTraffic() {

		if (getCriterion().getWagonExtId().trim().length() < 12)
			MessageUtils.setMessageError("wagon.extid.required");
		else
			try {
				String compMsg = hubManager.findWagonInTraffic(hub,
						getCriterion().getWagonExtId());
				MessageUtils.setMessageInfo("hub.wagon.found",
						new Object[] { compMsg });
			} catch (WagonNotFoundException e) {
				MessageUtils.setMessageError("hub.error.wagon");
			} catch (Exception e) {
				getErrorHandler(e);
			}
	}

	/**
	 * Cette méthode permet d'inverser la position des wagons dans une rame (que
	 * ce la soit à la reception ou au départ). On inverse la numérotation des
	 * wagons dans la table hub_compo et on met à jour le sillon.
	 */
	public void reverseSense() {

		try {
			setCurrentSillon(getLstSillons().get(getCriterion().getIdx()));
			getCurrentSillon().setReverseSense(getCriterion().isReverseSense());
			hubManager.reverseSense(getCurrentSillon());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Placement d'un wagon sur une voie et une position donnée, il s'agit d'une
	 * création potentielle d'un nouveau wagon (ou locomotive) par l'utilisateur
	 * (le wagon peut déjà exister en base), on place juste un objet vide wagon
	 * dans currentWagon pour le présenter à l'utilisateur, et on affiche la
	 * page de saisie.
	 */
	public void createNewWagon() {

		setCurrentWagon(new Wagon());
		// Cas particulier pour la liste déroulante de la position.
		getCurrentWagon().getNextPos().setPosNum(-1);
	}

	/**
	 * Suppression d'un wagon (ou d'une locomotive) à partir de la page de
	 * vidualisation des wagons sur une voie. Il faut vérifier que le wagon à
	 * supprimer ne fait pas partie d'un train déjà au départ. Si oui, on renvoi
	 * un message de confirmation pour spécifier au coordinateur que l'on va
	 * supprimer le wagon de la composition.
	 */
	public void deleteWagon() {
		try {
			hubManager.deleteWagon(getHub(), getCurrentWagon());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Si le coordinateur désire suprimer un wagon, on vérifie que ce dernier ne
	 * fait pas partie d'un lot pour la formation d'un train au départ. Si c'est
	 * le cas, on affiche un message d'avertissement au coordinateur pour lui
	 * spécifier le fait que l'on va aussi supprimer le wagon de la composition.
	 */
	public void checkWagonNotInFormationPlan() {

		try {
			hubManager.checkWagonNotInFormationPlan(getCurrentWagon());
		} catch (WagonAlreadyInFormationPlanException e) {
			MessageUtils.setMessageError("wagon.delete.departure");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Mise à jour de la disponiblité de la voie courante. Cette méthode permet
	 * au coordinateur de rendre la voie disponible ou non disponible sans avoir
	 * à aller dans le panneau de gestion des voies.
	 */
	public void updateRailAvailable() {

		try {
			Rail rail = getCurrentRail();
			rail.setAvailable(getCriterion().isRailAvailable());
			hubManager.updateRailAvailable(getCurrentRail());
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Demande de rafraîchissement du hub. On ne fait pas un rafraîchissement
	 * total des voies,on demande seulement le rafraîchissement des wagons sur
	 * les voies. Bien que théoriquement la matrice des wagons doit être
	 * exactement la représentation de ce qui est en base de données, on préfère
	 * toutefois retirer l'ensemble des données de la base afin de ne pas
	 * conserver de scories dans certains paramètres des wagons. On route
	 * ensuite sur la page demandée. Cela permet de plus, de boucler et de
	 * vérifier l'enregistrement des données dans la base.
	 */
	public String refreshHub() {

		try {
			hubManager.refreshHub(getHub());
			if ("null".equals(getCriterion().getFromOutCome())) {
				return null;
			}
			return getCriterion().getFromOutCome();
		} catch (Exception e) {
			getErrorHandler(e);
			return null;
		}
	}

	/**
	 * Méthode static pour pouvoir retrouver le bean dans la map session et
	 * demander le rafraichissement des ses informations à partir d'un autre
	 * managed bean. Si le bean n'est pas encore dans la map, on ne fait rien de
	 * particulier puisque ce dernier ira lire les informations au moment au il
	 * sera activé grâce à la méthode _get*.
	 */
	public static void refresh() {

		HubManagedBean hub = (HubManagedBean) ManagedBeanUtils
				.getExternalContext().getSessionMap().get("hubManaged");
		if (null != hub)
			hub._getHub();
	}

	// *********************************
	// Les getters et les setters.
	// *********************************

	public HubTrafficController getHub() {
		return hub;
	}

	public void setHub(HubTrafficController hub) {
		this.hub = hub;
	}

	public List<Composition> getLstCompositions() {
		return lstCompositions;
	}

	public void setLstCompositions(List<Composition> lstCompositions) {
		this.lstCompositions = lstCompositions;
	}

	public Criterion getCriterion() {
		return criterion;
	}

	public void setCriterion(Criterion criterion) {
		this.criterion = criterion;
	}

	public List<Sillon> getLstSillons() {
		return lstSillons;
	}

	public void setLstSillons(List<Sillon> lstSillons) {
		this.lstSillons = lstSillons;
	}

	public Sillon getCurrentSillon() {
		return currentSillon;
	}

	public void setCurrentSillon(Sillon currentSillon) {
		this.currentSillon = currentSillon;
	}

	public Wagon getCurrentWagon() {
		return currentWagon;
	}

	public void setCurrentWagon(Wagon currentWagon) {
		this.currentWagon = currentWagon;
	}

	public String getPdfFileToLoad() {
		return pdfFileToLoad;
	}

	public void setPdfFileToLoad(String pdfFileToLoad) {
		this.pdfFileToLoad = pdfFileToLoad;
	}

	public Rail getCurrentRail() {
		return currentRail;
	}

	public void setCurrentRail(Rail currentRail) {
		this.currentRail = currentRail;
	}
}
